package javaBasic.javaSE1.InnerClass;

/*
如果一个事物的内部包含另一个事物，那么这就是一个类内部包含另一个类。
例如：身体和心脏的关系。又如：汽车和发动机的关系。

分类：
1、成员内部类
2、局部内部类(包含匿名内部类)

成员内部类的定义格式：
修饰符 class 外部类名称 {
    修饰符 class 内部类名称 {
        //...
    }
    //....
}
注意：内用外，随意访问；外用内，需要内部类对象。

==========================
如何使用成员内部类？又两种方法：
1、间接方式：在外部类的方法当中，使用内部类的放啊，里面间接在使用内部类Heart
2、直接方式，公式：
类名称 对象名 = new 类名称();
【外部类名称.内部类名称 对象名 = new 外部类名称().new 内部类名称();】

内部类的同名变量访问
如果出现了重名现象，那么格式是：
外部类变量：外部类名称.内部类名称.this.外部类成员变量名
内部类变量：this.内部类成员变量名
 */

/*
局部内部类
如果一个类是定义在一个方法内部，那么这就是一个局部内部类。
"局部"：只有当前所属的方法才能使用它，除了这个方法外面就不能用了。

定义格式：
修饰符 class 外部类名称{
    修饰符 返回值类型 外部类方法名称(参数列表){
        class 局部内部类名称{
            //...
        }
    }
}
注意：局部内部类，如果希望访问所在方法的局部变量，那么这个局部变量必须是【有效final的】
备注：从java8+开始，只要局部变量事实不变，那么final关键字可以省略。
原因：
1、new出来的对象在堆内存当中。
2、局部变量是跟着方法走的，在栈内存当中。
3、方法运行结束后，立刻出栈，局部变量就会立刻消失。
4、但是new出来的对象会在堆当中持续存在，知道垃圾回收消失。

小结一下类的权限修饰符：
public>protected>(default)>private
定义一个类的时候，权限修饰符规则：
1、外部类：public / (default)
2、成员内部类：public / protected / (default) / private
3、局部内部类：什么都不能写
 */

/*
匿名内部类
如果接口的实现类(或者是父类的子类)只需要使用唯一一次，
那么这种情况下就可以省略调该类的定义，而改为使用【匿名内部类】。

匿名内部类的定义格式：
接口名称 对象名 = new 接口名称(){
    //覆盖重写所有抽象方法
}

堆格式 "new 接口名称() {...}"进行解析：
1、new代表创建对象的动作
2、接口名称就是匿名内部类需要实现那个接口
3、{...}这才是匿名内部类的内容

另外还要注意几点问题：
1、匿名内部类，在创建对象的时候只能使用一次
2、匿名对象，在【调用方法】的时候，只能调用唯一一次。
如果希望调用多次创建对象，调用多次方法，那么必须给对象起个名字
3、匿名内部类是声落了【实现类/子类名称】，但是匿名对象是省略类【对象名称】
强调：匿名内部类和匿名对象不是一回事

 */
public class Demo01InnerClass {

//    public static void main(String[] args) {
//        long a = System.currentTimeMillis();
//        for(int i=1;i<=9999;i++){
//            System.out.println(i);
//        }
//        long b = System.currentTimeMillis();
//        System.out.println(b-a);
//    }
}
